/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import bean.Apoio;
import bean.Autor;
import bean.Capitulo;
import bean.Colecao;
import bean.Editora;
import bean.Formato;
import bean.Idioma;
import bean.Instituicao;
import bean.Livro;
import bean.LivroOrganizado;
import bean.Tema;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.primefaces.model.LazyDataModel;


/**
 *
 * @author fernando
 */
public class LivroOrganizadoDao extends LazyDataModel<LivroOrganizado> implements Serializable  {

    private Conexao conexao;
    private PreparedStatement ps;
    private boolean sucess = false;

    public LivroOrganizadoDao() {
        this.conexao = new ConexaoPostgres();

    }

    public boolean cadastrarLivro(LivroOrganizado livro, Colecao colecao) {
        sucess = false;

        try {
            System.out.println("Cadastro Livro: ");
            System.out.println("Titulo: " + livro.getTitulo());


            ps = conexao.getConnection().prepareStatement("INSERT INTO Obra(ano, issn_isbn, quantidade_paginas, id_colecao, id_editora,  id_formato,  cidade_publicacao, uf_publicacao, indice, titulo, id_idioma, tipo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ");
            ps.setInt(1, livro.getAnoPublicacao());
            ps.setString(2, livro.getISSN_ISBN());
            ps.setInt(3, livro.getQuantidadePaginas());
            ps.setInt(4, colecao.getId());
            ps.setInt(5, livro.getEditora().getId());
            ps.setInt(6, livro.getFormato().getId());
            ps.setString(7, livro.getCidadePublicacao());
            ps.setString(8, livro.getUfPublicacao());
            ps.setString(9, livro.getIndice());
            ps.setString(10, livro.getTitulo());
            ps.setInt(11, livro.getIdioma().getId());
            ps.setString(12, "Livro Organizado");
            ps.executeUpdate();
            conexao.closeConnection();

            livro = this.consultaLivro(livro, colecao);
            System.out.println(livro.getId());
            if ((livro.getId() != -1) && (livro.getId() != 0)) { //-1 indica que por algum motivo ao consultar não foi encontrado o livro

                Iterator i = livro.getApoios().iterator();
                Apoio apoio = new Apoio();
                while (i.hasNext()) {
                    ps = conexao.getConnection().prepareStatement("INSERT INTO obra_apoio(id_obra, id_apoio) VALUES (?, ?)  ");
                    ps.setInt(1, livro.getId());
                    apoio = (Apoio) i.next();
                    ps.setInt(2, apoio.getId());
                    ps.executeUpdate();
                    conexao.closeConnection();

                }

                i = livro.getOrganizadores().iterator();
                Autor autor = new Autor();
                while (i.hasNext()) {
                    ps = conexao.getConnection().prepareStatement("INSERT INTO livro_organizadores(id_obra, id_organizador) VALUES (?, ?)  ");
                    ps.setInt(1, livro.getId());
                    autor = (Autor) i.next();
                    ps.setInt(2, autor.getId());
                    ps.executeUpdate();
                    conexao.closeConnection();

                }

                i = livro.getTemas().iterator();
                Tema tema = new Tema();
                while (i.hasNext()) {
                    ps = conexao.getConnection().prepareStatement("INSERT INTO obra_tema(id_obra, id_tema) VALUES (?, ?)  ");
                    ps.setInt(1, livro.getId());
                    tema = (Tema) i.next();
                    ps.setInt(2, tema.getId());
                    ps.executeUpdate();
                    conexao.closeConnection();

                }






            }

            sucess = true;

        } catch (SQLException ex) {
            conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
            return sucess;
        }

        conexao.closeConnection();
        return sucess;
    }

    public boolean alterarLivro(LivroOrganizado livro, Colecao colecao) {



        sucess = false;

        try {
            System.out.println("Edição Livro Organizado: ");
            System.out.println("Titulo: " + livro.getTitulo());


            ps = conexao.getConnection().prepareStatement("UPDATE Obra SET ano = ?, issn_isbn = ?, quantidade_paginas = ?,  id_colecao = ?, id_editora = ?, id_formato = ?, cidade_publicacao = ?, uf_publicacao = ?, indice = ?, titulo = ?, id_idioma = ?, tipo = ? WHERE id = ?");
            ps.setInt(1, livro.getAnoPublicacao());
            ps.setString(2, livro.getISSN_ISBN());
            ps.setInt(3, livro.getQuantidadePaginas());
            ps.setInt(4, colecao.getId());
            ps.setInt(5, livro.getEditora().getId());
            ps.setInt(6, livro.getFormato().getId());
            ps.setString(7, livro.getCidadePublicacao());
            ps.setString(8, livro.getUfPublicacao());
            ps.setString(9, livro.getIndice());
            ps.setString(10, livro.getTitulo());
            ps.setInt(11, livro.getIdioma().getId());
            ps.setString(12, "Livro Organizado");
            ps.setInt(13, livro.getId());
            ps.executeUpdate();
            conexao.closeConnection();

            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_apoio WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();

            Iterator i = livro.getApoios().iterator();
            while (i.hasNext()) {
                ps = conexao.getConnection().prepareStatement("INSERT INTO obra_apoio(id_obra, id_apoio) VALUES (?, ?)  ");
                ps.setInt(1, livro.getId());
                Apoio apoio = (Apoio) i.next();
                ps.setInt(2, apoio.getId());
                ps.executeUpdate();
                conexao.closeConnection();

            }

            //Remove Todos os elementos para inserir o que se alterar
            ps = conexao.getConnection().prepareStatement(" DELETE FROM livro_organizadores WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();


            i = livro.getOrganizadores().iterator();
            while (i.hasNext()) {
                ps = conexao.getConnection().prepareStatement("INSERT INTO livro_organizadores(id_obra, id_organizador) VALUES (?, ?)  ");
                ps.setInt(1, livro.getId());
                Autor autor = (Autor) i.next();
                ps.setInt(2, autor.getId());
                ps.executeUpdate();
                conexao.closeConnection();

            }


            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_tema WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();

            i = livro.getTemas().iterator();
            while (i.hasNext()) {
                ps = conexao.getConnection().prepareStatement("INSERT INTO obra_tema(id_obra, id_tema) VALUES (?, ?)  ");
                ps.setInt(1, livro.getId());
                Tema tema = (Tema) i.next();
                ps.setInt(2, tema.getId());
                ps.executeUpdate();
                conexao.closeConnection();

            }


            sucess = true;

        } catch (SQLException ex) {
            conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
            return sucess;
        }

        conexao.closeConnection();
        return sucess;
    }

    public boolean removerLivro(LivroOrganizado livro) {
        sucess = false;
        try {


            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_autor WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();



            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_apoio WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();



            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_tema WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();

            Iterator i;
            i = livro.getCapitulos().iterator();
            Capitulo c = new Capitulo();
            while (i.hasNext()) {
                ps = conexao.getConnection().prepareStatement(" DELETE FROM capitulo_autor WHERE id_capitulo = ?");
                c = (Capitulo) i.next();
                ps.setLong(1, c.getId());
                ps.executeUpdate();
                conexao.closeConnection();

                ps = conexao.getConnection().prepareStatement(" DELETE FROM capitulo WHERE id = ?");
                ps.setLong(1, (livro.getId()));
                ps.executeUpdate();
                conexao.closeConnection();
            }

            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra WHERE id = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();






            sucess = true;
        } catch (SQLException ex) {
            ex.printStackTrace();
            conexao.closeConnection();
            return sucess;
        }

        conexao.closeConnection();
        return sucess;
    }

    public ArrayList<Tema> buscarTemasLivro(LivroOrganizado livro) {
        ArrayList<Tema> temasObra = new ArrayList<Tema>();
        try {
            ps = conexao.getConnection().prepareStatement("SELECT t.id, t.tema FROM tema AS t, obra_tema AS ot, obra AS o "
                    + "WHERE o.id = ? AND o.id = ot.id_obra AND t.id = ot.id_tema;    ");
            ps.setInt(1, livro.getId());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Tema t = new Tema();
            while (rs.next()) {

                t.setId(rs.getInt("id"));
                t.setTema(rs.getString("tema"));


                temasObra.add(t);

                t = new Tema();

            }

        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(LivroDao.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.conexao.closeConnection();
        return temasObra;
    }

    public ArrayList<Apoio> buscarApoiosLivro(LivroOrganizado livro) {
        ArrayList<Apoio> apoiosObra = new ArrayList<Apoio>();
        try {
            ps = conexao.getConnection().prepareStatement("SELECT a.id, a.nome FROM apoio_formento AS a, obra_apoio AS oa, obra AS o "
                    + "WHERE o.id = ? AND o.id = oa.id_obra AND a.id = oa.id_apoio;   ");
            ps.setInt(1, livro.getId());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Apoio a = new Apoio();
            while (rs.next()) {

                a.setId(rs.getInt("id"));
                a.setNome(rs.getString("nome"));


                apoiosObra.add(a);

                a = new Apoio();

            }

        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(LivroDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.conexao.closeConnection();
        return apoiosObra;
    }

    public List<Autor> buscarOrganizadoresLivro(LivroOrganizado livro) {
        ArrayList<Autor> organizadoresObra = new ArrayList<Autor>();
        try {
            ps = conexao.getConnection().prepareStatement("SELECT a.id, a.restante_nome, a.ultimo_nome, a.id_instituicao, i.nome, i.estado, i.municipio, a.lattes "
                    + "FROM autor AS a, instituicao AS i, livro_organizadores AS lo, obra AS o "
                    + "WHERE o.id = ? AND o.id = lo.id_obra AND a.id = lo.id_organizador AND a.id_instituicao = i.id; ");
            ps.setInt(1, livro.getId());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Instituicao i = new Instituicao();
            Autor a = new Autor();
            while (rs.next()) {

                a.setId(rs.getInt("id"));
                a.setRestanteNome(rs.getString("restante_nome"));
                a.setUltimoNome(rs.getString("ultimo_nome"));
                a.setLattes(rs.getString("lattes"));
                i.setId(rs.getInt("id_instituicao"));
                i.setNome(rs.getString("nome"));
                i.setEstado(rs.getString("estado"));
                i.setMunicipio(rs.getString("municipio"));
                a.setInstituicaoAutor(i);

                organizadoresObra.add(a);

                a = new Autor();
                i = new Instituicao();
            }

        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(LivroDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.conexao.closeConnection();
        return organizadoresObra;

    }

    public List<Capitulo> buscarCapitulosLivro(LivroOrganizado livro) {
        CapituloDao cd = new CapituloDao();
        return cd.buscarCapitulosLivro(livro);

    }

    public List<LivroOrganizado> listarLivros() {
        List<LivroOrganizado> livros = new ArrayList<LivroOrganizado>();
        try {
            System.out.println("Fui Executado: Livro Organizado Dao  - listarLivros");
            ps = conexao.getConnection().prepareStatement("SELECT o.id, o.cidade_publicacao, o.uf_publicacao, o.ano, o.issn_isbn, o.quantidade_paginas, o.id_colecao, c.titulo AS colecao_titulo,  o.id_editora, e.nome, o.id_formato, f.tipo AS formato_tipo , o.id_idioma, i.idioma, o.tipo AS obra_tipo, o.indice, o.titulo AS obra_titulo  "
                    + "FROM obra AS o, idioma AS i, formato AS f, editora as e, colecao AS c "
                    + "WHERE o.tipo = 'Livro Organizado' AND o.id_editora = e.id AND o.id_colecao = c.id AND o.id_formato = f.id AND o.id_idioma = i.id  ORDER BY o.titulo");
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Editora ed = new Editora();
            Formato f = new Formato();
            Idioma i = new Idioma();

            while (rs.next()) {
                LivroOrganizado livro = new LivroOrganizado();
                Colecao colecao = new Colecao();

                livro.setId(rs.getInt("id"));
                livro.setAnoPublicacao(rs.getInt("ano"));
                livro.setISSN_ISBN(rs.getString("issn_isbn"));
                livro.setQuantidadePaginas(rs.getInt("quantidade_paginas"));
                livro.setCidadePublicacao(rs.getString("cidade_publicacao"));
                livro.setUfPublicacao(rs.getString("uf_publicacao"));

                colecao.setId(rs.getInt("id_colecao"));
                colecao.setNomeColecao(rs.getString("colecao_titulo"));

                ed.setId(rs.getInt("id_editora"));
                ed.setNome(rs.getString("nome"));
                livro.setEditora(ed);

                f.setId(rs.getInt("id_formato"));
                f.setFormato(rs.getString("formato_tipo"));
                livro.setFormato(f);

                i.setId(rs.getInt("id_idioma"));
                i.setIdioma(rs.getString("idioma"));
                livro.setIdioma(i);


                livro.setTipo(rs.getString("obra_tipo"));
                livro.setIndice(rs.getString("indice"));
                livro.setTitulo(rs.getString("obra_titulo"));
                livro.setOrganizadores((ArrayList) this.buscarOrganizadoresLivro(livro));
                livro.setCapitulos((ArrayList) this.buscarCapitulosLivro(livro));
                livro.setApoios(this.buscarApoiosLivro(livro));
                livro.setTemas(this.buscarTemasLivro(livro));

                livros.add(livro);



            }
        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
        }


        this.conexao.closeConnection();

        return livros;

    }

    //int ano, String issn_isbn, int quantidadepaginas, int id_colecao, int id_editora, int id_formato,  String cidade_publicacao, String uf_publicacao, String indice, String titulo
    public LivroOrganizado consultaLivro(LivroOrganizado livro, Colecao colecao) {
        this.ps = null;

        try {
            System.out.println("Livro Dao - Consulta Livro - Titulo: " + livro.getTitulo());

            ps = conexao.getConnection().prepareStatement("Select * from obra where titulo = ? and tipo = 'Livro Organizado'");
            ps.setString(1, livro.getTitulo());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();

            if (rs.next()) {
                System.out.println("Livro Dao - Descobrir id livro - Encontrado! = " + livro.getId());
                livro.setId(rs.getInt("id"));
                return livro;

            }
        } catch (SQLException ex) {
            conexao.closeConnection();
            return livro;

        }
        System.out.println("Livro Dao - Descobrir id livro - Não encontrou o livro!");

        livro.setId(-1); //-1 codigo para livro não encontrado!
        conexao.closeConnection();
        return livro;
    }

    public LivroOrganizado consultaLivro(int id) {
        this.ps = null;
        LivroOrganizado livro = new LivroOrganizado();
        Editora ed = new Editora();
        EditoraDao eDAO = new EditoraDao();
        Formato f = new Formato();
        FormatoDao fd = new FormatoDao();
        Idioma i = new Idioma();
        IdiomaDao iDAO = new IdiomaDao();
        Colecao colecao = new Colecao();

        try {
            System.out.println("Livro Dao - Consulta Livro por ID -  " + id);

            ps = conexao.getConnection().prepareStatement("Select * from obra where id = ? ");
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();


            if (rs.next()) {



                livro.setId(rs.getInt("id"));
                livro.setAnoPublicacao(rs.getInt("ano"));
                livro.setISSN_ISBN(rs.getString("issn_isbn"));
                livro.setQuantidadePaginas(rs.getInt("quantidade_paginas"));
                livro.setTipo(rs.getString("tipo"));
                livro.setIndice(rs.getString("indice"));
                livro.setTitulo(rs.getString("titulo"));
                livro.setCidadePublicacao(rs.getString("cidade_publicacao"));
                livro.setUfPublicacao(rs.getString("uf_publicacao"));

                /*
                 colecao.setId(rs.getInt("id_colecao"));
                 colecao.setNomeColecao(rs.getString("colecao_titulo"));
                 */
                ed = eDAO.consultarEditora(rs.getInt("id_editora"));
                livro.setEditora(ed);



                f = fd.consultarFormato(rs.getInt("id_formato"));
                livro.setFormato(f);

                i = iDAO.consultarIdioma(rs.getInt("id_idioma"));
                livro.setIdioma(i);



                livro.setOrganizadores((ArrayList) this.buscarOrganizadoresLivro(livro));
                livro.setCapitulos((ArrayList) this.buscarCapitulosLivro(livro));
                livro.setApoios(this.buscarApoiosLivro(livro));
                livro.setTemas(this.buscarTemasLivro(livro));


                conexao.closeConnection();



                return livro;





            }
        } catch (SQLException ex) {
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
            conexao.closeConnection();
            return livro;

        }
        System.out.println("LivroOrganizado Dao - Descobrir id livro - Não encontrou o livro!");

        livro.setId(-1); //-1 codigo para livro não encontrado!
        conexao.closeConnection();
        return livro;
    }

    

    public LivroOrganizado consultaDadosLivroOrganizado(int id) {
        this.ps = null;
        LivroOrganizado livro = new LivroOrganizado();
        Editora ed = new Editora();
        EditoraDao eDAO = new EditoraDao();
        Formato f = new Formato();
        FormatoDao fd = new FormatoDao();
        Idioma i = new Idioma();
        IdiomaDao iDAO = new IdiomaDao();
        Colecao colecao = new Colecao();

        try {
            System.out.println("Livro Dao - Consulta Livro por ID -  " + id);

            ps = conexao.getConnection().prepareStatement("Select * from obra where id = ? ");
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();


            if (rs.next()) {



                livro.setId(rs.getInt("id"));
                livro.setAnoPublicacao(rs.getInt("ano"));
                livro.setISSN_ISBN(rs.getString("issn_isbn"));
                livro.setQuantidadePaginas(rs.getInt("quantidade_paginas"));
                livro.setTipo(rs.getString("tipo"));
                livro.setIndice(rs.getString("indice"));
                livro.setTitulo(rs.getString("titulo"));
                livro.setCidadePublicacao(rs.getString("cidade_publicacao"));
                livro.setUfPublicacao(rs.getString("uf_publicacao"));

                /*
                 colecao.setId(rs.getInt("id_colecao"));
                 colecao.setNomeColecao(rs.getString("colecao_titulo"));
                 */
                ed = eDAO.consultarEditora(rs.getInt("id_editora"));
                livro.setEditora(ed);



                f = fd.consultarFormato(rs.getInt("id_formato"));
                livro.setFormato(f);

                i = iDAO.consultarIdioma(rs.getInt("id_idioma"));
                livro.setIdioma(i);



                livro.setOrganizadores((ArrayList) this.buscarOrganizadoresLivro(livro));

                livro.setApoios(this.buscarApoiosLivro(livro));
                livro.setTemas(this.buscarTemasLivro(livro));


                conexao.closeConnection();



                return livro;





            }
        } catch (SQLException ex) {
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
            conexao.closeConnection();
            return livro;

        }
        System.out.println("LivroOrganizado Dao - Descobrir id livro - Não encontrou o livro!");

        livro.setId(-1); //-1 codigo para livro não encontrado!
        conexao.closeConnection();
        return livro;
    }

    public LivroOrganizado buscarLivro(int id) {
        LivroOrganizado livro = new LivroOrganizado();
        try {

            ps = conexao.getConnection().prepareStatement("SELECT o.id, o.ano, o.issn_isbn, o.quantidade_paginas, o.id_colecao, c.titulo AS colecao_titulo,  o.id_editora, e.nome, o.id_formato, f.tipo AS formato_tipo , o.id_idioma, i.idioma, o.tipo AS obra_tipo, o.indice, o.titulo AS obra_titulo  "
                    + "FROM obra AS o, idioma AS i, formato AS f, editora as e, colecao AS c "
                    + "WHERE o.id = ? AND o.id_editora = e.id AND o.id_colecao = c.id AND o.id_formato = f.id AND o.id_idioma = i.id  ORDER BY o.titulo");
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Editora ed = new Editora();
            Formato f = new Formato();
            Idioma i = new Idioma();

            if (rs.next()) {

                Colecao colecao = new Colecao();

                livro.setId(rs.getInt("id"));
                livro.setAnoPublicacao(rs.getInt("ano"));
                livro.setISSN_ISBN(rs.getString("issn_isbn"));
                livro.setQuantidadePaginas(rs.getInt("quantidade_paginas"));

                colecao.setId(rs.getInt("id_colecao"));
                colecao.setNomeColecao(rs.getString("colecao_titulo"));

                ed.setId(rs.getInt("id_editora"));
                ed.setNome(rs.getString("nome"));
                livro.setEditora(ed);

                f.setId(rs.getInt("id_formato"));
                f.setFormato(rs.getString("formato_tipo"));
                livro.setFormato(f);

                i.setId(rs.getInt("id_idioma"));
                i.setIdioma(rs.getString("idioma"));
                livro.setIdioma(i);


                livro.setTipo(rs.getString("obra_tipo"));
                livro.setIndice(rs.getString("indice"));
                livro.setTitulo(rs.getString("obra_titulo"));
                livro.setOrganizadores((ArrayList) this.buscarOrganizadoresLivro(livro));
                livro.setCapitulos((ArrayList) this.buscarCapitulosLivro(livro));
                livro.setApoios(this.buscarApoiosLivro(livro));
                livro.setTemas(this.buscarTemasLivro(livro));




            }
        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
        }


        this.conexao.closeConnection();

        return livro;

    }
    
   
    
    
}
